package top.itaso.lib.java.singleton;

/**
 * @Description: DCL式(Double Check Lock)
 * 2、使用的时候即调用 getInstance 的时候才初始化
 * 3、static 关键字修饰，静态变量，存储在内存中，只有一份数据
 * 4、synchronized 线程安全，多线程情况下单例的唯一性
 * 5、两次判断空，避免多次同步 (synchronized)
 * 缺点
 * private static SingletonDLC mInstance;
 * private SingletonDLC() {}
 * public static SingletonDLC getmInstance() {}
 * 由于 jvm 特性，允许乱序执行，上面三句代码顺序不定，那么就可能出现 DCL 失效的问题。
 * 步骤一、倘若 A 线程执行 getmInstance(),还没执行构造方法 SingletonDLC()
 * 步骤二、此时 B 线程调用 getmInstance()。因为A已经执行 getmInstance()，所以 mInstance 不为空就直接获取。
 * 步骤三、由于 B 直接获取，而真实情况是 A 线程构造方法还未执行，所以 mInstance 就为空了。
 * 虽然此情况发生概率较小，但也是一种情况。为了解决这种情况，java1.6 开始加入 volatile 关键字（这样就避免了 DCL 方式失效的情况。虽然会 volatile 消耗一些性能，所以 DCL 最佳写法）
 * @Author Aso
 * @Date 2024/4/29
 */

public class SingletonDLC {

    private volatile static SingletonDLC mInstance;

    public static SingletonDLC getmInstance() {
        if (mInstance == null) {
            synchronized (SingletonDLC.class) {
                if (mInstance == null) {
                    mInstance = new SingletonDLC();
                }
            }
        }
        return mInstance;
    }

    private SingletonDLC() {
    }
}